package com.usian.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.usian.config.RedisClient;
import com.usian.mapper.TbItemParamItemMapper;
import com.usian.mapper.TbItemParamMapper;
import com.usian.pojo.TbItemParam;
import com.usian.pojo.TbItemParamExample;
import com.usian.pojo.TbItemParamItem;
import com.usian.pojo.TbItemParamItemExample;
import com.usian.service.TbItemParamService;
import com.usian.utils.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class TbItemParamServiceImpl implements TbItemParamService {

    @Autowired
    private TbItemParamMapper tbItemParamMapper;

    @Autowired
    private TbItemParamItemMapper tbItemParamItemMapper;

    @Autowired
    private RedisClient redisClient;

    @Value("${ITEM_INFO}")
    private String ITEM_INFO;

    @Value("${BASE}")
    private String BASE;

    @Value("${DESC}")
    private String DESC;

    @Value("${PARAM}")
    private String PARAM;

    @Value("${ITEM_INFO_EXPIRE}")
    private Long ITEM_INFO_EXPIRE;

    @Value("${SETNX_PARAM_LOCK_KEY}")
    private String SETNX_PARAM_LOCK_KEY;


    @Override
    public TbItemParam selectItemParamByItemCatId(Integer itemCatId) {
        TbItemParamExample example = new TbItemParamExample();
        TbItemParamExample.Criteria criteria = example.createCriteria();
        criteria.andItemCatIdEqualTo((long)itemCatId);
        List<TbItemParam> tbItemParams = tbItemParamMapper.selectByExampleWithBLOBs(example);
        if (tbItemParams.size()>0){
            return tbItemParams.get(0);
        }
        return null;
    }

    @Override
    public PageResult selectItemParamAll() {
        List<TbItemParam> list = tbItemParamMapper.selectByExampleWithBLOBs(null);
        PageResult pageResult = new PageResult();
        pageResult.setPageIndex(1);
        pageResult.setTotalPage(9);
        pageResult.setResult(list);
        return pageResult;
    }

    @Override
    public Boolean insertItemParam(Long itemCatId, String[] paramData) {
        TbItemParam tbItemParam = new TbItemParam();
        tbItemParam.setUpdated(new Date());
        tbItemParam.setCreated(new Date());
        tbItemParam.setItemCatId(itemCatId);
        StringBuilder paramDatas = new StringBuilder();
        for (String paramDatum : paramData) {
            paramDatas.append(paramDatum);
        }
        tbItemParam.setParamData(paramDatas.toString());
        int insertItemParam = tbItemParamMapper.insertSelective(tbItemParam);
        if (insertItemParam==1){
            return true;
        }
        return false;
    }

    @Override
    public Boolean deleteItemParamById(Long id) {
        int deleteItemParam = tbItemParamMapper.deleteByPrimaryKey(id);
        if (deleteItemParam==1){
            return true;
        }
        return false;
    }

    /**
     * 根据id查询分类信息
     * @param itemId
     * @return
     */
    @Override
    public TbItemParamItem selectTbItemParamItemByItemId(Long itemId) {
        /* 缓存中查询 缓存中存在直接返回 */
        TbItemParamItem tbItemParamItemRedis = (TbItemParamItem)redisClient.get(ITEM_INFO+":"+PARAM+":"+itemId);
        if (tbItemParamItemRedis!=null){
            return tbItemParamItemRedis;
        }

        /* 通过setnx实现添加分布式锁防止缓存击穿问题 并设置一个过期时间 防止死锁现象 */
        if (redisClient.setnx(SETNX_PARAM_LOCK_KEY+":"+itemId,itemId,30L)){
            /* 缓存中不存在查询数据库 */
            TbItemParamItemExample example = new TbItemParamItemExample();
            TbItemParamItemExample.Criteria criteria = example.createCriteria();
            criteria.andItemIdEqualTo(itemId);
            List<TbItemParamItem> tbItemParamItems = tbItemParamItemMapper.selectByExampleWithBLOBs(example);

            /* 判断数据库是否存在查询的数据  不存在的话缓存一个空数据并返回 */
            if (tbItemParamItems==null||tbItemParamItems.size()==0){
                tbItemParamItems = new ArrayList<>();
                tbItemParamItems.add(new TbItemParamItem(itemId,"数据有误"));
            }
            /* 存入redis并返回 */
            redisClient.set(ITEM_INFO+":"+PARAM+":"+itemId,tbItemParamItems);
            redisClient.expire(ITEM_INFO+":"+PARAM+":"+itemId,ITEM_INFO_EXPIRE);

            /* 处理完成 删除锁 */
            redisClient.del(SETNX_PARAM_LOCK_KEY+":"+itemId);
            return tbItemParamItems.get(0);
        }else {
            /* 没有抢到锁 休眠0.1s 继续抢夺锁资源 */
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return  selectTbItemParamItemByItemId(itemId);
        }

    }


}
